

#include <cegfx/ceeffect.h>
#include <stdio.h>

ceEffect* ceEffect::currentEffect = 0;

ceEffect::ceEffect ()
	: effect (0)
{
	IQF_CONSTRUCT;
}

ceEffect::~ceEffect ()
{
	if (effect)
	{
		effect->Release ();
	}
}

IQF_IMPLEMENTATION_BEGIN(ceEffect);
IQF_IMPLEMENTATION_END ();


void ceEffect::SetEffect (LPD3DXEFFECT effect)
{
	SAVE_SET(this->effect, effect);

	if (this->effect)
	{
		handleWorldMat	= effect->GetParameterBySemantic (NULL, "WORLD");
		handleViewMat		= effect->GetParameterBySemantic (NULL, "VIEW");
		handleProjMat		= effect->GetParameterBySemantic (NULL, "PROJ");

		handleMatAmbient = effect->GetParameterBySemantic (NULL, "MATERIALAMBIENT");
		handleMatDiffuse = effect->GetParameterBySemantic (NULL, "MATERIALDIFFUSE");
		handleMatSpecular = effect->GetParameterBySemantic (NULL, "MATERIALSPECULAR");
		handleMatEmissive = effect->GetParameterBySemantic (NULL, "MATERIALEMISSIVE");
		handleMatPower = effect->GetParameterBySemantic (NULL, "MATERIALPOWER");

		handleLightAmbient = effect->GetParameterBySemantic (NULL, "LIGHTAMBIENT");
		handleLightDiffuse = effect->GetParameterBySemantic (NULL, "LIGHTDIFFUSE");
		handleLightSpecular = effect->GetParameterBySemantic (NULL, "LIGHTSPECULAR");
		handleLightPosition = effect->GetParameterBySemantic (NULL, "LIGHTPOSITION");
		handleLightDirection = effect->GetParameterBySemantic (NULL, "LIGHTDIRECTION");
		handleLightRange = effect->GetParameterBySemantic (NULL, "LIGHTRANGE");

		handleTextureDiffuse = effect->GetParameterBySemantic (NULL, "TEXTUREDIFFUSE");
		handleTextureSpecular = effect->GetParameterBySemantic (NULL, "TEXTURESPECULAR");
		handleTextureBump = effect->GetParameterBySemantic (NULL, "TEXTUREBUMP");
		handleTextureEffect0 = effect->GetParameterBySemantic (NULL, "TEXTUREEFFECT0");
	}

}

LPD3DXEFFECT ceEffect::GetEffect ()
{
	return effect;
}


void ceEffect::SetProjMatrix (const D3DXMATRIX& mat)
{
	effect->SetMatrix (handleProjMat, &mat);
}

void ceEffect::SetViewMatrix (const D3DXMATRIX& mat)
{
	effect->SetMatrix (handleViewMat, &mat);
}

void ceEffect::SetWorldMatrix (const D3DXMATRIX& mat)
{
	effect->SetMatrix (handleWorldMat, &mat);
}


#define DEBUG_MATRIX(m)							\
	printf ("%.2f %.2f %.2f %.2f\n", m._11, m._12, m._13, m._14); \
	printf ("%.2f %.2f %.2f %.2f\n", m._21, m._22, m._23, m._24); \
	printf ("%.2f %.2f %.2f %.2f\n", m._31, m._32, m._33, m._34); \
	printf ("%.2f %.2f %.2f %.2f\n", m._41, m._42, m._43, m._44);

void ceEffect::SetMatrices (const D3DXMATRIX& proj, const D3DXMATRIX& view, const D3DXMATRIX& world)
{
	effect->SetMatrix (handleProjMat,  &proj);
	effect->SetMatrix (handleViewMat,  &view);
	effect->SetMatrix (handleWorldMat, &world);
}

void ceEffect::SetMaterial (const D3DMATERIAL9& material)
{
	if (handleMatAmbient)
	{
		effect->SetVector (handleMatAmbient, (const D3DXVECTOR4*)(&material.Ambient));
	}
	if (handleMatDiffuse)
	{
		effect->SetVector (handleMatDiffuse, (const D3DXVECTOR4*)(&material.Diffuse));
	}
	if (handleMatSpecular)
	{
		effect->SetVector (handleMatSpecular, (const D3DXVECTOR4*)(&material.Specular));
	}
	if (handleMatEmissive)
	{
		effect->SetVector (handleMatEmissive, (const D3DXVECTOR4*)(&material.Emissive));
	}
	if (handleMatPower)
	{
		effect->SetFloat (handleMatPower, material.Power);
	}
}

void ceEffect::SetLight (const D3DLIGHT9& light)
{
	if (handleLightAmbient)
	{
		effect->SetVector (handleLightAmbient, (const D3DXVECTOR4*)(&light.Ambient));
	}
	if (handleLightDiffuse)
	{
		effect->SetVector (handleLightDiffuse, (const D3DXVECTOR4*)(&light.Diffuse));
	}
	if (handleLightSpecular)
	{
		effect->SetVector (handleLightSpecular, (const D3DXVECTOR4*)(&light.Specular));
	}
	if (handleLightPosition)
	{
		effect->SetVector (handleLightPosition, (const D3DXVECTOR4*)(&light.Position));
	}
	if (handleLightDirection)
	{
		effect->SetVector (handleLightDirection, (const D3DXVECTOR4*)(&light.Direction));
	}
	if (handleLightRange)
	{
		effect->SetFloat (handleLightRange, light.Range);
	}

}

void ceEffect::SetDiffuseTexture (LPDIRECT3DTEXTURE9 diffuse)
{
	if (handleTextureDiffuse)
	{
		effect->SetTexture (handleTextureDiffuse, diffuse);
	}
}


void ceEffect::SetSpecularTexture (LPDIRECT3DTEXTURE9 specular)
{
	if (handleTextureSpecular)
	{
		effect->SetTexture (handleTextureSpecular, specular);
	}
}


void ceEffect::SetBumpTexture (LPDIRECT3DTEXTURE9 bump)
{
	if (handleTextureBump)
	{
		effect->SetTexture (handleTextureBump, bump);
	}
}

void ceEffect::SetEffect0Texture (LPDIRECT3DTEXTURE9 texture)
{
	if (handleTextureEffect0)
	{
		effect->SetTexture (handleTextureEffect0, texture);
	}
}


D3DXHANDLE ceEffect::GetHandleByName (const char* handleName)
{
	return effect->GetParameterByName (NULL, handleName);
}

D3DXHANDLE ceEffect::GetHandleBySemantic (const char* handleName)
{
	return effect->GetParameterBySemantic (NULL, handleName);
}

void ceEffect::SetVector (D3DXHANDLE handle, const D3DXVECTOR4* vec)
{
	effect->SetVector (handle, vec);
}

void ceEffect::SetVertices (D3DXHANDLE handle, unsigned num, const D3DXVECTOR4* vec)
{
	effect->SetVectorArray (handle, vec, num);
}

void ceEffect::SetMatrix (D3DXHANDLE handle, const D3DXMATRIX* matrix)
{
	effect->SetMatrix (handle, matrix);
}

void ceEffect::SetMatrices (D3DXHANDLE handle, unsigned num, const D3DXMATRIX* matrices)
{
	effect->SetMatrixArray (handle, matrices, num);
}


unsigned ceEffect::Begin ()
{
	ceEffect::currentEffect = this;

	unsigned passes;
	effect->Begin (&passes, 0);
	return passes;
}

void ceEffect::BeginPass (unsigned pass)
{
	effect->BeginPass (pass);
}

void ceEffect::EndPass ()
{
	effect->EndPass ();
}

void ceEffect::End ()
{
	effect->End ();

	ceEffect::currentEffect = 0;
}

ceEffect* ceEffect::GetCurrentEffect ()
{
	return ceEffect::currentEffect;
}

